package com.um.jdy.platform.shop.manager;

import cn.hutool.core.util.NumberUtil;
import cn.hutool.core.util.StrUtil;
import com.um.jdy.common.activity.service.CouponsUserService;
import com.um.jdy.common.finance.entity.po.PlatformBill;
import com.um.jdy.common.finance.enums.FinancialEnum;
import com.um.jdy.common.finance.service.PlatformBillService;
import com.um.jdy.common.market.entity.po.Group;
import com.um.jdy.common.market.service.GroupService;
import com.um.jdy.common.member.entity.po.MemberUser;
import com.um.jdy.common.member.enums.PayEnum;
import com.um.jdy.common.member.service.MemberUserService;
import com.um.jdy.common.shop.entity.po.ReturnSetting;
import com.um.jdy.common.shop.service.ReturnSettingService;
import com.um.jdy.common.shop.code.ShopOrderCode;
import com.um.jdy.common.shop.entity.po.Order;
import com.um.jdy.common.shop.entity.po.OrderAftersaleDynamic;
import com.um.jdy.common.shop.entity.vo.OrderGoodsVO;
import com.um.jdy.common.shop.entity.vo.OrderVO;
import com.um.jdy.common.shop.enums.AftersaleEnum;
import com.um.jdy.common.shop.enums.OrderEnum;
import com.um.jdy.common.shop.service.*;
import com.um.jdy.common.shop.entity.po.OrderAftersale;
import com.um.jdy.common.shop.entity.dto.OrderAftersaleDTO;
import com.um.jdy.common.shop.entity.vo.OrderAftersaleVO;
import com.um.jdy.common.commons.manager.WxManager;
import com.um.jdy.platform.shop.entity.vo.*;
import com.um.springboot.starter.entity.Page;
import com.um.springboot.starter.exception.ServiceException;
import com.um.springboot.starter.orm.manager.BasePlusManager;
import com.um.springboot.starter.orm.params.ListDTO;
import com.um.springboot.starter.orm.params.PageDTO;
import com.um.springboot.starter.orm.params.PageParams;
import com.um.springboot.starter.utils.*;
import com.um.weixin.pay.service.WxBasePayService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 管理类：订单店铺售后表
 */
@Slf4j
@Component
public class OrderAftersaleManager extends BasePlusManager<OrderAftersaleService,OrderAftersale,OrderAftersaleDTO,OrderAftersaleVO, PageDTO, ListDTO> {

    @Autowired
    OrderGoodsService orderGoodsService;

    @Autowired
    ShopOrderService shopOrderService;

    @Autowired
    MemberUserService memberUserService;

    @Autowired
    OrderAftersaleDynamicService orderAftersaleDynamicService;

    @Autowired
    GoodsOptionService goodsOptionService;

    @Autowired
    CouponsUserService couponsUserService;

    @Autowired
    ReturnSettingService shopSettingService;

    @Autowired
    WxManager wxManager;

    @Autowired
    WxBasePayService wxBasePayService;

    @Autowired
    private PlatformBillService platformBillService;

    @Autowired
    private GroupService groupService;

    /**
     * 分页查询售后订单
     * @param pageParams
     * @return
     */
    public Page<OrderAftersaleItemVO> getPage(PageParams pageParams) {

        Page<OrderAftersaleItemVO> page = new Page<>();
        page.setPageNo(pageParams.getPageNo());
        page.setPageSize(pageParams.getPageSize());

        pageParams.getCondition().put("a.com_id", getComId());

        page = service.getCMSViewModelPageBySqlName(page, "shop_get_order_aftersale_page", "shop_get_order_aftersale_count",
                OrderAftersaleItemVO.class, pageParams.getProperties(), pageParams.getValues(),
                pageParams.getRangeEntitys(), pageParams.getOrderNames(), pageParams.getSortOns());

        page.getResult().stream().forEach(item -> {
            List<OrderGoodsVO> goodsList = orderGoodsService.getViewModelList("get_order_aftersale_goods_list",
                    OrderGoodsVO.class,new Object[]{item.getShopOrderAftersaleId(),orderGoodsService.getComId()});
            item.setGoods(goodsList);
        });

        OrderAftersaleSummaryVO extraDataVO = service.getCMSViewModelBySqlName("shop_get_order_aftersale_summary",OrderAftersaleSummaryVO.class, pageParams.getProperties(), pageParams.getValues(),
                pageParams.getRangeEntitys());
        long refundCount = service.getCountBySqlName("shop_get_order_aftersale_type_count",new Object[]{getComId(),AftersaleEnum.Type.Refund.name()});
        long barterCount = service.getCountBySqlName("shop_get_order_aftersale_type_count",new Object[]{getComId(),AftersaleEnum.Type.ReturnRefund.name()});
        long reissueCount = service.getCountBySqlName("shop_get_order_aftersale_type_count",new Object[]{getComId(),AftersaleEnum.Type.Reissue.name()});
        long exchangeCount = service.getCountBySqlName("shop_get_order_aftersale_type_count",new Object[]{getComId(),AftersaleEnum.Type.Exchange.name()});

        extraDataVO.setRefundCount(refundCount);
        extraDataVO.setExchangeCount(exchangeCount);
        extraDataVO.setBarterCount(barterCount);
        extraDataVO.setReissueCount(reissueCount);

        page.setExtraData(extraDataVO);

        return page;
    }

    /**
     * 售后订单详情
     *
     * @param orderAftersaleId
     * @return
     */
    public OrderAftersaleDetailVO getAftersale(String orderAftersaleId) {
        OrderAftersale orderAftersale = service.getEntity(orderAftersaleId);
        if(orderAftersale == null){
            throw new ServiceException(ShopOrderCode.OrderAftersaleNoExist);
        }

        List<OrderGoodsVO> goodsList = orderGoodsService.getViewModelList("get_order_aftersale_goods_list",
                OrderGoodsVO.class,new Object[]{orderAftersaleId,orderGoodsService.getComId()});

        Order shopOrder = shopOrderService.getEntity(orderAftersale.getShopOrderId());
        if(shopOrder == null){
            throw new ServiceException(ShopOrderCode.OrderNoExist);
        }

        MemberUser memberUser = memberUserService.getEntity(shopOrder.getMemberUserId());
        ShopOrderDetailVO orderDetailVO = UMBeanUtils.copyBean(shopOrder,ShopOrderDetailVO.class);

        if(memberUser != null){
            orderDetailVO.setNickname(memberUser.getNickname());
            orderDetailVO.setPhoto(memberUser.getPhoto());
        }

        OrderAftersaleDetailVO orderAftersaleDetailVO = UMBeanUtils.copyBean(orderAftersale,OrderAftersaleDetailVO.class);
        orderAftersaleDetailVO.setGoods(goodsList);
        orderAftersaleDetailVO.setOrderDetail(orderDetailVO);

        return orderAftersaleDetailVO;
    }

    /**
     * 同意售后
     *
     * @param orderAftersaleId
     * @return
     */
    public boolean agree(String orderAftersaleId) {
        OrderAftersale orderAftersale = service.getEntity(orderAftersaleId);
        if(orderAftersale == null){
            throw new ServiceException(ShopOrderCode.OrderAftersaleNoExist);
        }

        if(!StringUtil.equals(orderAftersale.getStatus(), AftersaleEnum.Status.UnReview.name())){
            throw new ServiceException(ShopOrderCode.AgreeFailureForNotUnreview);
        }

        boolean result;

        //仅退款
        if(StringUtil.equals(orderAftersale.getType(),AftersaleEnum.Type.Refund.name())){
            result = this.refundAftersale(orderAftersaleId);
        }else{
            orderAftersale.setStatus(AftersaleEnum.Status.UnSendBack.name());

            ReturnSetting shopSetting = shopSettingService.getEntity("com_id", orderAftersale.getComId());
            if(null != shopSetting){
               orderAftersale.setReturnProvince(shopSetting.getProvince());
               orderAftersale.setReturnCity(shopSetting.getCity());
               orderAftersale.setReturnArea(shopSetting.getArea());
               orderAftersale.setReturnAddress(shopSetting.getAddress());
               orderAftersale.setReturnLinkman(shopSetting.getLinkman());
               orderAftersale.setReturnPhone(shopSetting.getPhone());
            }

            result = service.update(orderAftersale);

            this.saveDynamic(orderAftersale);
        }

//        Map user = extraDao.queryRealMap(TableName.APP_ACCOUNT,orderAftersale.get("app_account_id"));
//        subscribeMessageService.saveAftersaleAuditMessage(StringUtil.getTrim(user.get("app_account_id")),
//                StringUtil.getTrim(user.get("open_id")),
//                StringUtil.getTrim(orderAftersale.get("aftersale_no")),
//                StringUtil.getTrim(AftersaleOrderType.getValue(StringUtil.getTrim(orderAftersale.get("type")))),
//                StringUtil.getTrim("审批通过"),
//                StringUtil.getTrim(DateUtil.parse(StringUtil.getTrim(orderAftersale.get("create_time"))).toString()),
//                StringUtil.getTrim("点击查看售后详情"),
//                "/pages/order/afterSale/detail?mall_order_aftersale_id="+mallOrderShopAftersaleId
//        );

        return result;
    }

    /**
     * 售后退款
     *
     * @param orderAftersaleId
     * @return
     */
    public boolean refundAftersale(String orderAftersaleId) {

        OrderAftersale orderAftersale = service.getEntity(orderAftersaleId);
        if(orderAftersale == null){
            throw new ServiceException(ShopOrderCode.OrderAftersaleNoExist);
        }

        if(!(StringUtil.equals(orderAftersale.getStatus(),AftersaleEnum.Status.Refund.name()) && StringUtil.equals(orderAftersale.getType(),AftersaleEnum.Type.ReturnRefund.name())) &&
                !(StringUtil.equals(orderAftersale.getStatus(),AftersaleEnum.Status.UnReview.name()) && StringUtil.equals(orderAftersale.getType(),AftersaleEnum.Type.Refund.name())) ){
            throw new ServiceException("30025");
        }

        Order order = shopOrderService.getEntity(orderAftersale.getShopOrderId());

        //退款金额
        List<OrderGoodsVO> goodsList = orderGoodsService.getViewModelList("get_order_aftersale_goods_list",
                OrderGoodsVO.class,new Object[]{orderAftersaleId,orderGoodsService.getComId()});
        for(OrderGoodsVO orderGoodsVO : goodsList){
            //退回已退款商品库存
            goodsOptionService.addStock(orderGoodsVO.getShopGoodsOptionId(),orderGoodsVO.getNum());

            //如果是活动商品退活动库存
            if(!StringUtil.isEmpty(orderGoodsVO.getMarketActivityId())){
                goodsOptionService.addActivityStock(orderGoodsVO.getMarketActivityGoodsOptionId(),orderGoodsVO.getNum());
            }
        }
        //退款平台流水
        platformBillService.addBill(order.getComId(), orderAftersale.getAftersaleNo(), order.getOrderNo(), orderAftersale.getAmount(),
                FinancialEnum.IncomeOrExpend.Expend, FinancialEnum.PlatformBillEvent.GoodsRefund, FinancialEnum.BillStatus.Effective);

       //退回退款金额手续费
        PlatformBill wxpayChargeBill = platformBillService.getRow(new String[]{"order_no", "event"},
                new Object[]{order.getOrderNo(), FinancialEnum.PlatformBillEvent.PayFee.name()});
        if(null != wxpayChargeBill && wxpayChargeBill.getAmount() > 0){
           int refundChargeAmount = orderAftersale.getAmount() / order.getPayment() * wxpayChargeBill.getAmount();
           platformBillService.addBill(order.getComId(), orderAftersale.getAftersaleNo(), order.getOrderNo(), refundChargeAmount,
                   FinancialEnum.IncomeOrExpend.Income, FinancialEnum.PlatformBillEvent.PayFeeRefund, FinancialEnum.BillStatus.Effective);
        }

//        //退款分销流水
//        if(StrUtil.isNotEmpty(distributeAccountId) && commission>0){
//            //退佣金平台流水
//            this.saveBill(StringUtil.getTrim(order.get("order_no")), StringUtil.getTrim(orderAftersale.get("aftersale_no")), commission, IncomeOrExpend.INCOME.getKey(), BillType.REFUND_DISTRIBUTE_COMMISSION.getKey(), BillStatus.ECTICVE.getKey(), "");
//            //退款分销佣金金额账单
//            this.saveSellerBill(StringUtil.getTrim(order.get("distribute_account_id")), StringUtil.getTrim(order.get("order_no")), StringUtil.getTrim(orderAftersale.get("aftersale_no")), commission, IncomeOrExpend.EXPEND.getKey(), DistributeBillType.REFUND.getKey(), BillStatus.NOT_ECTICVE.getKey(), "");
//        }


        orderAftersale.setStatus(AftersaleEnum.Status.Completed.name());
        service.update(orderAftersale);
        this.saveDynamic(orderAftersale);


        //判断该订单是否所有商品都已退款
        boolean allRefund = true;
        List<OrderGoodsAftersaleItemVO> orderGoodsList = service.getViewModelList("get_order_goods_list",OrderGoodsAftersaleItemVO.class,new Object[]{order.getShopOrderId(),service.getComId()});
        for(OrderGoodsAftersaleItemVO orderGoods : orderGoodsList){
            if(!OrderEnum.GoodsType.FullReduce.name().equals(orderGoods.getType()) &&
                    (StringUtil.equals(orderGoods.getAftersaleType(),AftersaleEnum.Type.Exchange.name())
                    || !StringUtil.equals(orderGoods.getAftersaleStatus(),AftersaleEnum.Status.Completed.name()))){
                allRefund = false;
                break;
            }
        }

        if(allRefund){
            order.setStatus(OrderEnum.Status.Return.name());
            shopOrderService.update(order);

            orderAftersale.setAmount(NumberUtil.add(orderAftersale.getAmount(), order.getDeliveryPrice()).intValue());
            service.update(orderAftersale);

            //退回优惠券
            couponsUserService.returnCouponsUse(order.getActivityCouponsUserId());

            //订单已结束，修改分销佣金账单状态
//            List<Map> billSellerList = dao.queryList(TableName.SELLER_BILL, new String[]{"order_no"}, new Object[]{order.get("order_no")});
//            for (Map bill : billSellerList) {
//                bill.put("status", BillStatus.ECTICVE.getKey());
//                this.saveRecord(TableName.SELLER_BILL, bill);
//            }

        }

        //退款
        if (PayEnum.PayWay.Wxpay.name().equals(order.getPayWay())) {
            try {
                wxManager.getPayService(order.getComId());
                wxBasePayService.refundOrder(order.getOutTradeNo(), orderAftersale.getAftersaleNo(),
                        PayUtil.toTotalFee(order.getPayment()), PayUtil.toTotalFee(orderAftersale.getAmount()));
            } catch (Exception ex) {
                log.error(StrUtil.format("售后订单[{}]微信退款错误", order.getOrderNo()), ex);
            }

        }

        //拼团订单检查是否要关闭团
        if(StrUtil.equals(order.getType(), OrderEnum.Type.Group.name())){
            Group group = groupService.getRow(order.getMarketGroupId());
            if(null == group){
                return true;
            }

            //如果拼团没有人了就关闭团
            List<OrderVO> groupOrderList = shopOrderService.getViewModelList("get_effective_group_order_list",
                    OrderVO.class, new Object[]{order.getMarketGroupId(),shopOrderService.getComId()});
            if(groupOrderList.size() == 0){
                group.setShopOrderIds(order.getShopOrderId());
                group.setStatus(OrderEnum.GroupStatus.Invalid.name());
                groupService.updateRow(group);
                log.info("系统关闭没有团员的团购，拼团id：{}", order.getMarketGroupId());
            }else if(OrderEnum.GroupStatus.Unopen.name().equals(group.getStatus())){
                group.setShopOrderIds(groupOrderList.stream().map(item -> item.getShopOrderId()).collect(Collectors.joining(",")));
                groupService.updateRow(group);
            }
        }


        return true;

    }

    /**
     * 拒绝售后
     *
     * @param orderAftersaleId
     * @return
     */
    public boolean rejectAftersale(String orderAftersaleId,String rejectReason) {
        OrderAftersale orderAftersale = service.getEntity(orderAftersaleId);
        if(orderAftersale == null){
            throw new ServiceException(ShopOrderCode.OrderAftersaleNoExist);
        }

        if(!StringUtil.equals(orderAftersale.getStatus(), AftersaleEnum.Status.UnReview.name()) &&
                !StringUtil.equals(orderAftersale.getStatus(), AftersaleEnum.Status.Refund.name())){
            throw new ServiceException(ShopOrderCode.RefuseAftersaleFailure);
        }

        orderAftersale.setStatus(AftersaleEnum.Status.Reject.name());
        orderAftersale.setRejectReason(rejectReason);

        this.saveDynamic(orderAftersale);

//        Map user = extraDao.queryRealMap(TableName.APP_ACCOUNT,orderAftersale.get("app_account_id"));
//        subscribeMessageService.saveAftersaleAuditMessage(StringUtil.getTrim(user.get("app_account_id")),
//                StringUtil.getTrim(user.get("open_id")),
//                StringUtil.getTrim(orderAftersale.get("aftersale_no")),
//                StringUtil.getTrim(AftersaleOrderType.getValue(StringUtil.getTrim(orderAftersale.get("type")))),
//                StringUtil.getTrim("审批驳回"),
//                StringUtil.getTrim(DateUtil.parse(StringUtil.getTrim(orderAftersale.get("create_time"))).toString()),
//                StringUtil.getTrim(rejectReason),
//                "/pages/order/afterSale/detail?mall_order_aftersale_id="+mallOrderShopAftersaleId
//        );

        return service.update(orderAftersale);
    }

    /**
     * 售后订单发货
     *
     * @param orderAftersaleId
     * @param courier
     * @param courierNo
     * @return
     */
    public boolean deliveryAftersale(String orderAftersaleId, String courier, String courierNo) {
        OrderAftersale orderAftersale = service.getEntity(orderAftersaleId);
        if(orderAftersale == null){
            throw new ServiceException(ShopOrderCode.OrderAftersaleNoExist);
        }

        if(!StringUtil.equals(orderAftersale.getStatus(),AftersaleEnum.Status.UnSend.name())){
            throw new ServiceException(ShopOrderCode.DeliveryFailureForNotUnsend);
        }

        orderAftersale.setCourier(courier);
        orderAftersale.setCourierNo(courierNo);
        orderAftersale.setStatus(AftersaleEnum.Status.UnReceive.name());
        orderAftersale.setDeliveryTime(new Date());

        this.saveDynamic(orderAftersale);

//        //生成用户订单动态
//        List<Map> goodsList = dao.queryListBySQLName("get_order_goods_aftersale_detail",new Object[]{orderAftersale.get("mall_order_aftersale_id")});
//        String goodsName = StringUtil.getTrim(goodsList.get(0).get("goods_name"));
//        if(goodsList.size() > 1){
//            goodsName = goodsName+"等"+goodsList.size()+"件商品";
//        }
//        Map user = extraDao.queryRealMap(TableName.APP_ACCOUNT,orderAftersale.get("app_account_id"));
//        subscribeMessageService.saveDeliveryMessage(StringUtil.getTrim(user.get("app_account_id"))
//                ,StringUtil.getTrim(user.get("open_id"))
//                ,StringUtil.getTrim(orderAftersale.get("aftersale_no"))
//                ,DateUtil.parse(StringUtil.getTrim(orderAftersale.get("delivery_time"))).toString()
//                ,StringUtil.getTrim(orderAftersale.get("courier"))
//                ,StringUtil.getTrim(orderAftersale.get("courier_no"))
//                ,goodsName,
//                "/pages/order/afterSale/detail?mall_order_aftersale_id="+mallOrderShopAftersaleId);

        return service.update(orderAftersale);
    }

    /**
     * 记录售后动态
     * @param orderAftersale
     */
    private void saveDynamic(OrderAftersale orderAftersale){
        String title = "";
        switch (AftersaleEnum.Status.valueOf(orderAftersale.getStatus())){
            case UnReview:
                title = "您的"+AftersaleEnum.Type.valueOf(orderAftersale.getType()).getValue()+"售后申请已提交，等待商家审批";
                break;
            case UnSendBack:
                title = "商家已同意您的"+AftersaleEnum.Type.valueOf(orderAftersale.getType()).getValue()+"售后申请，请尽快寄回商品";
                break;

            case UnSend:
                title = "您已寄回商品，等待商家收货后即寄出商品";
                break;

            case UnReceive:
                title = "商家已寄出换货商品";
                break;

            case Refund:
                title = "您已寄回商品，等待商家收货后即可退款";
                break;

            case Reject:
                title = "商家已拒绝您的"+AftersaleEnum.Type.valueOf(orderAftersale.getType()).getValue()+"售后申请，拒绝原因："+orderAftersale.getRejectReason();
                break;

            case Cancelled:
                title = "您的"+AftersaleEnum.Type.valueOf(orderAftersale.getType()).getValue()+"售后申请已取消";
                break;

            case Completed:
                if(StringUtil.equals(orderAftersale.getType(),AftersaleEnum.Type.Exchange.name())){
                    title = "您已确认收到换货商品，售后已完成";
                }else{
                    title = "商家已操作退款，售后已完成";
                }
                break;
        }

        OrderAftersaleDynamic dynamic = new OrderAftersaleDynamic();
        dynamic.setShopOrderAftersaleId(orderAftersale.getShopOrderAftersaleId());
        dynamic.setTitle(title);
        dynamic.setCreateTime(new Date());
        orderAftersaleDynamicService.add(dynamic);
    }
}
